using System.Security.Cryptography;
using System.Text;
using System.Text.Json;

namespace LicenseApp.Producer;

/// <summary>
/// 授权码生成器
/// </summary>
public class LicenseGenerator
{
    /// <summary>
    /// 授权信息数据结构
    /// </summary>
    public class LicenseData
    {
        public string StartDate { get; set; } = "";
        public int Days { get; set; }
        public int AgvCount { get; set; }
        public string MachineCode { get; set; } = "";  // 机器码（可选）
        public string Signature { get; set; } = "";
    }

    /// <summary>
    /// 为指定客户生成授权码
    /// </summary>
    /// <param name="customerName">客户名称</param>
    /// <param name="startDate">生效开始日期</param>
    /// <param name="days">授权天数</param>
    /// <param name="agvCount">AGV设备数量</param>
    /// <param name="machineCode">机器码（可选，为空表示不绑定机器）</param>
    /// <returns>Base64编码的授权码，失败返回null</returns>
    public static string? GenerateLicense(string customerName, DateTime startDate, int days, int agvCount, string machineCode = "")
    {
        try
        {
            // 获取客户私钥
            var privateKeyXml = KeyManager.GetPrivateKey(customerName);
            if (string.IsNullOrEmpty(privateKeyXml))
                return null;

            // 创建授权数据
            var licenseData = new LicenseData
            {
                StartDate = startDate.ToString("yyyy-MM-dd"),
                Days = days,
                AgvCount = agvCount,
                MachineCode = machineCode ?? ""  // 机器码可选
            };

            // 序列化为JSON
            var jsonData = JsonSerializer.Serialize(licenseData, new JsonSerializerOptions 
            { 
                WriteIndented = false 
            });

            // 使用私钥签名
            using var rsa = RSA.Create();
            rsa.FromXmlString(privateKeyXml);
            
            var dataBytes = Encoding.UTF8.GetBytes(jsonData);
            var signatureBytes = rsa.SignData(dataBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
            
            // 将签名添加到授权数据
            licenseData.Signature = Convert.ToBase64String(signatureBytes);

            // 重新序列化包含签名的完整数据
            var finalJsonData = JsonSerializer.Serialize(licenseData, new JsonSerializerOptions 
            { 
                WriteIndented = false 
            });

            // 返回Base64编码的授权码
            var licenseCode = Convert.ToBase64String(Encoding.UTF8.GetBytes(finalJsonData));

            // 保存授权码到客户目录
            KeyManager.SaveCustomerLicense(customerName, licenseCode);

            return licenseCode;
        }
        catch
        {
            return null;
        }
    }

    /// <summary>
    /// 验证授权码格式（用于生产工具测试）
    /// </summary>
    /// <param name="customerName">客户名称</param>
    /// <param name="licenseCode">授权码</param>
    /// <returns>验证结果和授权信息</returns>
    public static (bool IsValid, LicenseData? Data) ValidateLicense(string customerName, string licenseCode)
    {
        try
        {
            // 获取客户公钥
            var publicKeyXml = KeyManager.GetPublicKey(customerName);
            if (string.IsNullOrEmpty(publicKeyXml))
                return (false, null);

            // 解码Base64
            var jsonBytes = Convert.FromBase64String(licenseCode);
            var jsonData = Encoding.UTF8.GetString(jsonBytes);

            // 反序列化JSON
            var licenseData = JsonSerializer.Deserialize<LicenseData>(jsonData);
            if (licenseData == null || string.IsNullOrEmpty(licenseData.Signature))
                return (false, null);

            // 提取签名
            var signature = Convert.FromBase64String(licenseData.Signature);

            // 创建用于验证的数据（不包含签名）
            var dataForVerification = new LicenseData
            {
                StartDate = licenseData.StartDate,
                Days = licenseData.Days,
                AgvCount = licenseData.AgvCount,
                MachineCode = licenseData.MachineCode
            };

            var verificationJson = JsonSerializer.Serialize(dataForVerification, new JsonSerializerOptions 
            { 
                WriteIndented = false 
            });

            // 使用公钥验证签名
            using var rsa = RSA.Create();
            rsa.FromXmlString(publicKeyXml);
            
            var dataBytes = Encoding.UTF8.GetBytes(verificationJson);
            var isSignatureValid = rsa.VerifyData(dataBytes, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

            return (isSignatureValid, licenseData);
        }
        catch
        {
            return (false, null);
        }
    }

    /// <summary>
    /// 检查授权是否在有效期内
    /// </summary>
    /// <param name="licenseData">授权数据</param>
    /// <returns>是否有效</returns>
    public static bool IsLicenseActive(LicenseData licenseData)
    {
        try
        {
            if (DateTime.TryParse(licenseData.StartDate, out var startDate))
            {
                var endDate = startDate.AddDays(licenseData.Days);
                var now = DateTime.Now.Date;
                return now >= startDate.Date && now <= endDate.Date;
            }
            return false;
        }
        catch
        {
            return false;
        }
    }

    /// <summary>
    /// 获取授权剩余天数
    /// </summary>
    /// <param name="licenseData">授权数据</param>
    /// <returns>剩余天数，-1表示已过期或无效</returns>
    public static int GetRemainingDays(LicenseData licenseData)
    {
        try
        {
            if (DateTime.TryParse(licenseData.StartDate, out var startDate))
            {
                var endDate = startDate.AddDays(licenseData.Days);
                var now = DateTime.Now.Date;
                
                if (now > endDate.Date)
                    return -1; // 已过期
                
                if (now < startDate.Date)
                    return licenseData.Days; // 还未生效，返回总天数
                
                return (int)(endDate.Date - now).TotalDays;
            }
            return -1;
        }
        catch
        {
            return -1;
        }
    }
}
